#include "ServerComboBox.h"

#include <core/ImageMgr.h>
#include <core/StyleMgr.h>

#include <QAbstractItemView>
#include <QPaintEvent>
#include <QStandardItemModel>
#include <QStyleOptionViewItem>
#include <QStylePainter>
#include <QStyledItemDelegate>
#include <QVBoxLayout>

#include "StartupDlg.h"

class CbItemDelegate : public QStyledItemDelegate {
 public:
  CbItemDelegate(QComboBox* parent)
      : QStyledItemDelegate(parent), m_cb(parent) {}
  virtual void paint(QPainter* painter, const QStyleOptionViewItem& option,
                     const QModelIndex& index) const override {
    // painter->setRenderHint(QPainter::Antialiasing);
    painter->save();
    QRect r = option.rect;
    QString txt = index.data(Qt::DisplayRole).toString();
    NetStatus status = (NetStatus)index.data(Qt::DecorationRole).toInt();
    bool suggested = index.data(Qt::DisplayPropertyRole).toBool();

    bool hover =
        (option.state &
         QStyle::
             State_MouseOver);  // 这个判断不靠谱!:
                                // r.contains(option.widget->mapFromGlobal(QCursor::pos()));

    QColor bkColor = hover ? StyleMgr::instance().color("Hover")
                           : StyleMgr::instance().color("BackNormal");
    painter->setBrush(bkColor);
    painter->setPen(bkColor);
    painter->drawRect(r);

    float ratio = painter->device()->devicePixelRatioF();
    int spacing = 8;
    QRect checkR = r;
    checkR.setRight(checkR.left());
    SImage* imgCheck = ImgMgr::instance().image("widgets_dropdown_check",
                                                WidgetStatus::kPressed, ratio);
    if (imgCheck) {
      checkR.setLeft(checkR.left() + spacing);
      checkR.setRight(checkR.left() + imgCheck->width() - 1);
      checkR.setTop(r.top() + (r.height() - imgCheck->height()) / 2);
      checkR.setBottom(checkR.top() + imgCheck->height() - 1);
      if (index.row() == m_cb->currentIndex())
        painter->drawImage(checkR, *imgCheck);
    }

    r.setLeft(checkR.right() + spacing);
    QColor txtColor = m_cb->currentIndex() == index.row()
                          ? StyleMgr::instance().color("Highlight")
                          : StyleMgr::instance().color("TextNormal");
    painter->setPen(txtColor);
    painter->drawText(r, txt, QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
    if (suggested) {
      int width = option.fontMetrics.horizontalAdvance(txt);
      r.adjust(width, 0, 0, 0);
      QFont f = option.font;
      f.setPixelSize(10);
      painter->setFont(f);
      painter->drawText(r, tr("(推荐)"),
                        QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
    }

    QString imgName;
    switch (status) {
      case UnAvaiable:
        imgName = "auth_netsignal_no";
        break;
      case VeryBad:
        imgName = "auth_netsignal_weak";
        break;
      case Bad:
        imgName = "auth_netsignal_medium";
        break;
      case Good:
        imgName = "auth_netsignal_strong";
        break;
      default:
        break;
    }

    SImage* img =
        ImgMgr::instance().image(imgName, WidgetStatus::kNormal, ratio);
    if (img) {
      int w = img->width();
      int h = img->height();
      r.setLeft(r.right() - w);
      r.setWidth(w);
      r.setTop(r.top() + (r.height() - h) / 2);
      r.setHeight(h);
      painter->drawImage(r, *img);
    }

    painter->restore();
  }

 private:
  QComboBox* m_cb = nullptr;
};

ServerCombox::ServerCombox(QWidget* p) : SComboBox(p) {
  setItemDelegate(new CbItemDelegate(this));
}

void ServerCombox::paintEvent(QPaintEvent* e) {
  SComboBox::paintEvent(e);
  QColor txtColor = m_showPopup ? StyleMgr::instance().color("Highlight")
                                : StyleMgr::instance().color("TextNormal");

  QStylePainter painter(this);
  painter.setRenderHint(QPainter::Antialiasing);
  QRect r = rect();

  QModelIndex index = this->model()->index(currentIndex(), 0);
  QString txt = index.data(Qt::DisplayRole).toString();
  NetStatus status = (NetStatus)index.data(Qt::DecorationRole).toInt();
  bool suggested = index.data(Qt::DisplayPropertyRole).toBool();
  if (suggested) {
    QStyleOptionComboBox opt;
    initStyleOption(&opt);
    QRect txtRect = style()->subControlRect(QStyle::CC_ComboBox, &opt,
                                            QStyle::SC_ComboBoxEditField, this);

    QFontMetrics fm(font());
    int width = fm.horizontalAdvance(txt);
    txtRect.setLeft(txtRect.left() + width);

    QFont f = font();
    f.setPixelSize(10);
    painter.setFont(f);
    painter.setPen(txtColor);
    painter.drawText(txtRect, tr("(推荐)"),
                     QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
  }

  QString imgName;
  switch (status) {
    case UnAvaiable:
      imgName = "auth_netsignal_no";
      break;
    case VeryBad:
      imgName = "auth_netsignal_weak";
      break;
    case Bad:
      imgName = "auth_netsignal_medium";
      break;
    case Good:
      imgName = "auth_netsignal_strong";
      break;
    default:
      break;
  }
  SImage* img = ImgMgr::instance().image(imgName, WidgetStatus::kNormal,
                                         devicePixelRatioF());
  if (img) {
    int w = img->width();
    int h = img->height();
    r.setLeft(r.right() - 42);
    r.setWidth(w);
    r.setTop((rect().height() - h) / 2);
    r.setHeight(h);
    painter.drawImage(r, *img);
  }
}
